package com.gy.mbaselibrary.download;

import android.annotation.SuppressLint;
import android.app.DownloadManager;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import com.gy.mbaselibrary.utils.FileUtil;
import com.gy.mbaselibrary.utils.TimeUtil;

import java.io.File;
import java.io.IOException;

/**
 * 创建者：高业
 * 邮箱：15234150168@163.com
 * 时间：2018/2/6
 * 描述：
 * 修改人：
 * 修改时间：2018/2/6
 * 修改备注：
 */
public class DownloadManagerUtil implements TimeUtil.TimeMesListener {
    private Context mContext;
    private long downloadId;
    private String url;
    private DownloadChangeObserver downloadObserver;
    //private ScheduledExecutorService scheduledExecutorService;
    private TimeUtil timeUtil;
    public static final int HANDLE_DOWNLOAD = 0x001;
    private UpdateListener updateListener;
    private String path;

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getUrl() {
        return url;
    }

    public long getDownloadId() {
        return downloadId;
    }

    public void setUpdateListener(UpdateListener updateListener) {
        this.updateListener = updateListener;
    }

    private DownloadManagerUtil(){}


    public DownloadManagerUtil(Context context,String url) {
        this.mContext = context;
        this.url = url;
        this.downloadObserver = new DownloadChangeObserver();
    }

    /*public long download(String title, String desc) {
        Uri uri = Uri.parse(url);
        DownloadManager.Request req = new DownloadManager.Request(uri);
        //设置WIFI下进行更新
        req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
        //下载中和下载完后都显示通知栏
        req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        //使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0
        req.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, title);
        //通知栏标题
        req.setTitle(title);
        //通知栏描述信息
        req.setDescription(desc);
        //获取下载任务ID
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        return dm.enqueue(req);
    }

    public long download(String url,String name) {
        Uri uri = Uri.parse(url);
        DownloadManager.Request req = new DownloadManager.Request(uri);
        //设置WIFI下进行更新
        req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
        //下载中和下载完后都显示通知栏
        //使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0
        req.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, name);
        //获取下载任务ID
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        return dm.enqueue(req);
    }*/

    public void download(String title,String mes) {
        registerContentObserver();
        Uri uri = Uri.parse(url);
        DownloadManager.Request req = new DownloadManager.Request(uri);
        //设置WIFI下进行更新
        req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
        req.allowScanningByMediaScanner();
        //通知栏标题
        req.setTitle(title);
        //通知栏描述信息
        req.setDescription(mes);
        //下载完成之后也不会消失，直到点击或清除
        req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        //使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0
        String name = title + System.currentTimeMillis() + FileUtil.getFileType(url);
        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SxtmDownload/video/";
        File pathFile = new File(path);
        if (!pathFile.exists()){
            pathFile.mkdir();
        }
        File dFile = new File(path + name);
        if (dFile.exists()){
            dFile.delete();
        }
        //req.setDestinationInExternalFilesDir(mContext, path, name);
        //在SD卡上创建一个文件夹
        req.setDestinationInExternalPublicDir("/SxtmDownload/video/" , name);
        //获取下载任务ID
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        downloadId = dm.enqueue(req);
        setPath(path + name);
    }

    public void download() {
        registerContentObserver();
        Uri uri = Uri.parse(url);
        DownloadManager.Request req = new DownloadManager.Request(uri);
        req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
        //使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0
        String name = System.currentTimeMillis() + FileUtil.getFileName(url);
        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SxtmDownload/apk/";
        //不显示通知栏
        req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
        //这个文件是你的应用所专用的,软件卸载后，下载的文件将随着卸载全部被删除
        //req.setDestinationInExternalFilesDir(mContext, path, name);
        req.setDestinationInExternalPublicDir("/SxtmDownload/apk/" , name);
        File pathFile = new File(path);
        if (!pathFile.exists()){
            pathFile.mkdir();
        }
        File dFile = new File(path + name);
        if (dFile.exists()){
            dFile.delete();
        }
        //获取下载任务ID
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        downloadId = dm.enqueue(req);

        setPath(path + name);
    }

    /**
     * 注册ContentObserver
     */
    private void registerContentObserver() {
        /** observer download change **/
        if (downloadObserver != null) {
            mContext.getContentResolver().registerContentObserver(
                    Uri.parse("content://downloads/my_downloads"), false, downloadObserver);
        }
    }

    /**
     * 下载前先移除前一个任务，防止重复下载
     */
    public void clearCurrentTask() {
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        try {
            dm.remove(downloadId);
            close();
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void timeMesListener(long allTime, long shengTime, long cishu) {
        updateProgress();
    }

    @Override
    public void timeStartListener(long allTime) {

    }

    @Override
    public void timeFinishListener() {

    }


    /**
     * 监听下载进度
     */
    private class DownloadChangeObserver extends ContentObserver {

        public DownloadChangeObserver() {
            super(downLoadHandler);
            timeUtil = new TimeUtil();
            timeUtil.excuse(50,DownloadManagerUtil.this);
            //scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        }

        /**
         * 当所监听的Uri发生改变时，就会回调此方法
         * @param selfChange 此值意义不大, 一般情况下该回调值false
         */
        @Override
        public void onChange(boolean selfChange) {
            //scheduledExecutorService.scheduleAtFixedRate(progressRunnable, 0, 1, TimeUnit.SECONDS); //在子线程中查询
        }
    }

    @SuppressLint("HandlerLeak")
    public Handler downLoadHandler = new Handler() { //主线程的handler
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (updateListener != null && HANDLE_DOWNLOAD == msg.what) {
                //被除数可以为0，除数必须大于0
                if (msg.arg1 >= 0 && msg.arg2 > 0) {
                    updateListener.update(downloadId,(float) msg.arg1 * 100f / (float) msg.arg2);
                }
            }
        }
    };

    private Runnable progressRunnable = new Runnable() {
        @Override
        public void run() {
            updateProgress();
        }
    };

    /**
     * 发送Handler消息更新进度和状态
     * 将查询结果从子线程中发往主线程（handler方式），以防止ANR
     */
    private void updateProgress() {
        int[] bytesAndStatus = getBytesAndStatus(downloadId);
        downLoadHandler.sendMessage(downLoadHandler.obtainMessage(HANDLE_DOWNLOAD, bytesAndStatus[0], bytesAndStatus[1], bytesAndStatus[2]));
    }

    /**
     * 关闭定时器，线程等操作
     */
    private void close() {
        /*if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown()) {
            scheduledExecutorService.shutdown();
        }*/
        timeUtil.onDestory();
        if (downLoadHandler != null) {
            downLoadHandler.removeCallbacksAndMessages(null);
        }
    }





    public interface UpdateListener{
        public void update(long downloadId, float percent);
    }

    public interface FinishListener{
        public void finish(long downloadId);
    }


    /**
     * 通过query查询下载状态，包括已下载数据大小，总大小，下载状态
     *
     * @param downloadId
     * @return
     */
    private int[] getBytesAndStatus(long downloadId) {
        int[] bytesAndStatus = new int[]{
                -1, -1, 0
        };
        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor cursor = null;
        try {
            DownloadManager downloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
            cursor = downloadManager.query(query);
            if (cursor != null && cursor.moveToFirst()) {
                //已经下载文件大小
                bytesAndStatus[0] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                //下载文件的总大小
                bytesAndStatus[1] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                //下载状态
                bytesAndStatus[2] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return bytesAndStatus;
    }
}

